package com.hansen.library.ui.activity;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.StringRes;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

import com.hansen.library.R;
import com.hansen.library.ui.widget.dialog.LoadingDialog;
import com.hansen.library.ui.fragment.BaseFragment;
import com.hansen.library.utils.FastClickUtils;
import com.hansen.library.utils.LogUtils;
import com.hansen.library.utils.StringUtils;

/**
 * activity 基类
 *
 * Created by han on 2019/6/10 0010.
 */

public abstract class BaseActivity extends AppCompatActivity implements View.OnClickListener {

    protected Context mContext;

    //进度加载框
    private LoadingDialog mLoadingDialog;

    private boolean destroyed = false;

    private Handler mHandler;

    private FragmentTransaction mTransaction;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getResID());
        initView();
        initData(savedInstanceState);
        initListener();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    public void onClick(View v) {
        //防止快速点击
        if (FastClickUtils.isFastClick()) {
            return;
        }

        widgetClick(v);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            View view = getCurrentFocus();
            if (view != null && isShouldHideKeyBoard(view, ev)) {
                hideKeyboard(view.getWindowToken());
            }
        }
        return super.dispatchTouchEvent(ev);
    }

    /**
     * 抽象方法子类必须实现
     */
    protected abstract int getResID();

    protected abstract void initView();

    protected abstract void initData(Bundle savedInstanceState);

    protected abstract void initListener();

    public abstract void widgetClick(View v);

    public void showKeyboard(EditText editText) {
        if(editText == null) {
            return;
        }

        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

        imm.showSoftInput(editText, 0);
    }

    //隐藏软键盘
    public void hideKeyboard(IBinder windowToken) {
        InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

        if (im.isActive() && windowToken != null) {
            im.hideSoftInputFromWindow(windowToken, InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

    //判断是否需要隐藏软键盘
    private boolean isShouldHideKeyBoard(View view, MotionEvent ev) {
        if (view != null && (view instanceof EditText)) {
            int[] l = {0, 0};
            view.getLocationInWindow(l);
            int left = l[0];
            int top = l[1];
            int bottom = top + view.getHeight();
            int right = left + view.getWidth();
            if (ev.getX() > left && ev.getX() < right && ev.getY() > top && ev.getY() < bottom) {
                //点击EditText事件，忽略
                return false;
            } else {
                return true;
            }
        }
        // 如果焦点不是EditText则忽略，这个发生在视图刚绘制完，第一个焦点不在EditText上，和用户用轨迹球选择其他的焦点
        return false;
    }

    /**
     * fragment management
     */
    public BaseFragment addFragment(BaseFragment mTargetFragment, int mResId) {
        return addFragment(mTargetFragment, mResId, false);
    }

    public BaseFragment addFragment(BaseFragment mTargetFragment, int mResId, boolean needAddToBackStack) {
        if(mTargetFragment == null) {
            return null;
        }

        mTransaction = getSupportFragmentManager().beginTransaction();

        mTransaction.add(mResId, mTargetFragment);

        if (needAddToBackStack) {
            mTransaction.addToBackStack(null);
        }

        try {
            mTransaction.commitAllowingStateLoss();
        } catch (Exception e) {
            LogUtils.e("switch fragment exception" + e.getMessage());
        }

        return mTargetFragment;
    }

    protected BaseFragment replaceFragment(BaseFragment fragment, int containerViewId) {
        return replaceFragment(fragment, false, containerViewId);
    }

    protected BaseFragment replaceFragment(BaseFragment fragment, boolean needAddToBackStack, int containerViewId) {
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fm.beginTransaction();
        fragmentTransaction.replace(containerViewId, fragment);
        if (needAddToBackStack) {
            fragmentTransaction.addToBackStack(null);
        }
        try {
            fragmentTransaction.commitAllowingStateLoss();
        } catch (Exception e) {
            LogUtils.e("commitAllowingStateLoss exception: " + e.getMessage());
        }

        return fragment;
    }

    public BaseFragment switchFragment(BaseFragment mCurrentFragment, BaseFragment mTargetFragment, int containerViewId) {
        return switchFragment(mCurrentFragment, mTargetFragment, containerViewId, false);
    }

    protected BaseFragment switchFragment(BaseFragment mCurrentFragment, BaseFragment mTargetFragment, int mResId, boolean needAddToBackStack) {
        if (mCurrentFragment == null || mTargetFragment == null || mCurrentFragment == mTargetFragment) {

            return mTargetFragment;
        }

        mTransaction = getSupportFragmentManager().beginTransaction();

        if (mTargetFragment.isAdded()) {
            mTransaction.hide(mCurrentFragment).show(mTargetFragment);
        } else {
            mTransaction.hide(mCurrentFragment).add(mResId, mTargetFragment);
        }

        if (needAddToBackStack) {
            mTransaction.addToBackStack(null);
        }

        try {
            mTransaction.commitAllowingStateLoss();
        } catch (Exception e) {
            LogUtils.e("switch fragment exception" + e.getMessage());
        }

        return mTargetFragment;
    }

    //显示加载进度
    protected void showLoadingDialog() {
        showLoadingDialog(R.string.text_waiting_loading);
    }

    //显示加载进度
    protected void showLoadingDialog(@StringRes int resId) {
        showLoadingDialog(getString(resId));
    }

    //显示加载进度
    protected void showLoadingDialog(String res) {
        if (mLoadingDialog == null) {
            mLoadingDialog = new LoadingDialog(BaseActivity.this)
                    .builder()
                    .setCanceledOnTouchOutside(false)
                    .setCanceled(false);
        }

        mLoadingDialog.setTitle(res);

        if (!mLoadingDialog.isShowing()) {
            mLoadingDialog.show();
        }
    }

    protected void dismissDialog() {
        if (mLoadingDialog != null) {
            mLoadingDialog.dismiss();
        }
    }

    protected final Handler getHandler() {
        if (mHandler == null) {
            mHandler = new Handler(getMainLooper());
        }
        return mHandler;
    }

    public boolean isDestroyedCompatible() {
        if (Build.VERSION.SDK_INT >= 17) {
            return isDestroyedCompatible17();
        } else {
            return destroyed || super.isFinishing();
        }
    }

    @TargetApi(17)
    private boolean isDestroyedCompatible17() {
        return super.isDestroyed();
    }

    @Override
    protected void onDestroy() {
        if(mHandler != null) {
            mHandler.removeCallbacksAndMessages(null);
            mHandler = null;
        }
        mTransaction = null;
        mContext = null;
        destroyed = true;
        super.onDestroy();
    }
}

